#include "ReadRawFile.h"
#include "sndarecord.pb.h"
#include "operationfun.h"
#include <stdio.h>
#include <stdlib.h>

static char * readstring(char *);
static unsigned long long readuint64(char *);
static void readkeyprimer(char *, keyprimer a[3]);

static void swapkeyprimer(keyprimer &a, keyprimer &b)
{
    keyprimer c;
    c = a;
    a = b;
    b = c;
}

bool ReadkeybaserecordFromBuff(char * src, keybaserecord & record)
{
    
//"everbox"|"everbox/4_8dK0Cjw0A4jIOSDHdRbcK9bT8="|"0"|"1"|"92699"|"1316188413835"|"1316188413835"|"fgXAng98lv7Mx//nPolk5Q=="|"RMwyYw8hxRxlCQOefSL1HQ=="|"[{\"disk\":{\"host\":\"10.176.16.6\",\"id\":\"c932e79d-d405-4757-b93b-a44976e970df\"},\"chunk\":0,\"id\":11273},{\"disk\":{\"host\":\"10.176.18.2\",\"id\":\"833a81c4-7465-4aae-9138-22e15d6fe14c\"},\"chunk\":0,\"id\":11762},{\"disk\":{\"host\":\"10.176.20.1\",\"id\":\"a96523d0-af2e-4c00-a27e-b707d142d363\"},\"chunk\":0,\"id\":12592}]"|"{\"Content-MD5\":\"nDkkce8kU9katue+nRJ4qA==\",\"Content-Type\":\"binary/octet-stream\"}"|"{}"
//"everbox"|"everbox/7Q7iCID-HtzCFeodWUnzRul90gM="|"0"|"1"|"4194304"|"1316302874148"|"1316302874148"|"qT5qSoXUjGgk5qKvO5e7Tw=="|"KNizcj2EHTxZxyhMn5zwbg=="|"[{\"disk\":{\"host\":\"10.176.20.10\",\"id\":\"1be62053-6156-4042-bca1-721b87b0b123\"},\"chunk\":0,\"id\":17954},{\"disk\":{\"host\":\"10.176.18.2\",\"id\":\"833a81c4-7465-4aae-9138-22e15d6fe14c\"},\"chunk\":0,\"id\":18657},{\"disk\":{\"host\":\"10.176.16.4\",\"id\":\"0f8d2977-5288-4b75-9792-a3372b18c211\"},\"chunk\":0,\"id\":18829}]"|"{\"Content-MD5\":\"lbmKPKox9pygCXtb1zPmIA==\",\"Content-Type\":\"binary/octet-stream\"}"|"{}"
    
    char * charpoint[14] = { 0 };
    char * p = src;
    int i = 0;
    charpoint[0] = p;
    
    while(*p)
    {
        if(*p == '|')
        {
            *p = 0;
            ++i;
            charpoint[i] = p + 1;
        }
        p++;
    }

    if(i == 11)
    {
        record.set_bucket(readstring(charpoint[0]));
        record.set_indexkey(readstring(charpoint[1]));
        record.set_del_mark((bool)readuint64(charpoint[2]));
        record.set_version((char)readuint64(charpoint[3]));
        record.set_content_length(readuint64(charpoint[4]));
        record.set_user_time_stamp(readuint64(charpoint[5]));
        record.set_internal_time_stamp(readuint64(charpoint[6]));
        
        record.set_value_checksum(readstring(charpoint[7]));
        record.set_row_checksum(readstring(charpoint[8]));
        keyprimer readkeyerprimer[3];
        readkeyprimer(charpoint[9], readkeyerprimer);
        keyprimer * pkeyprimer = NULL;
        pkeyprimer = record.mutable_disk1();
        *pkeyprimer = readkeyerprimer[0];
        pkeyprimer = record.mutable_disk2();
        *pkeyprimer = readkeyerprimer[1];
        
        pkeyprimer = record.mutable_disk3();
        *pkeyprimer = readkeyerprimer[2];
        
        //record.set_disk2(readkeyerprimer[1]);
        //record.set_disk3(readkeyerprimer[2]);
        keyprimer a = record.disk1();
        keyprimer b = record.disk2();
        keyprimer c = record.disk3();
        
        record.set_system_metas(charpoint[10]);
        record.set_user_metas(charpoint[11]);
    }
    else
    {
        printf("wrong");
        exit(0);
        
    }
    return true;
}

static char * readstring(char * p)
{
    char * result = NULL;
    if(*p == '"')
    {
        result = p + 1;
        ++p;
    }

    while(*p)
    {
        if(*p == '"')
        {
            *p = 0;
            break;
        }
        ++p;
    }
    
    return result;
    
}

static char * readjsonstring(char * p)
{
    char * result = p;
    if(*p == '"')
    {
        result = p + 1;
        ++p;
    }

    while(*p)
    {
        if((*p == '"') || (*p == '\\') || (*p == ',') || (*p == '}'))
        {
            *p = 0;
            break;
        }
        ++p;
    }
    
    return result;
    
}

static unsigned long long readuint64(char *p)
{
    char * result = NULL;
    if(*p == '"')
    {
        result = p + 1;
        ++p;
    }

    while(*p)
    {
        if(*p == '"')
        {
            *p = 0;
            break;
        }
        ++p;
        
    }
    unsigned long long x = 0;
#ifdef WIN32
    x = (unsigned long long)_atoi64(result);
#else
    x = (unsigned long long)atoll(result);
#endif
    return x;
    
}

//[{\"disk\":{\"host\":\"10.176.20.10\",\"id\":\"1be62053-6156-4042-bca1-721b87b0b123\"},\"chunk\":0,\"id\":17954},
// {\"disk\":{\"host\":\"10.176.18.2\",\"id\":\"833a81c4-7465-4aae-9138-22e15d6fe14c\"},\"chunk\":0,\"id\":18657},
//{\"disk\":{\"host\":\"10.176.16.4\",\"id\":\"0f8d2977-5288-4b75-9792-a3372b18c211\"},
//\"chunk\":0,//\"id\":18829}]

static void readkeyprimer(char * p, keyprimer a[3])
{
    int indexofcolon = -1;
    
    char * phost = NULL;
    char *diskid = NULL;
    char *chunk = NULL;
    char *pid = NULL;
    char * src = p;
    int len = strlen(p);
    unsigned long long x = 0;
    for(int i = 0; i < len; ++i)
    {
        if(*p == ':')
        {
            ++indexofcolon;
            int v = indexofcolon % 5;
            
            if(v != 3)
            {
                p++;
            }
            if(*(p) = '\\')
            {
                p++;
            }
            switch(v)
            {
                case 0:

                    break;
                case 1:

                    phost = p;
                    break;
                case 2:
                    diskid = p;
                    
                    break;
                case 3:
                    chunk = p;
                    
                    break;
                case 4:
                    pid = p;
                    
                    a[indexofcolon / 5].set_host(readjsonstring(phost));
                    a[indexofcolon / 5].set_diskid(readjsonstring(diskid));
#ifdef WIN32
                    x = (unsigned long long)_atoi64(readjsonstring(chunk));
#else
                    x = (unsigned long long)atoll(readjsonstring(chunk));
#endif
                    a[indexofcolon / 5].set_chunk(x);
                    
#ifdef WIN32
                    x = (unsigned long long)_atoi64(readjsonstring(pid));
#else
                    x = (unsigned long long)atoll(readjsonstring(pid));
#endif
                    a[indexofcolon / 5].set_id(x);
                    
                    phost = diskid = chunk = pid = NULL;
                    
                    break;
                    
            }
            p++;
        }
        p++;
        
    }

    // sort keyprimer
    operation_KeyPrimer oper;
    if(!oper(&a[0], &a[1]))
    {
        swapkeyprimer(a[0], a[1]);
    }
    if(!oper(&a[0], &a[2]))
    {
        swapkeyprimer(a[0], a[2]);
        
    }
    
    if(!oper(&a[1], &a[2]))
    {
        swapkeyprimer(a[1], a[2]);
        
    }
}
